import { Mesh } from "three/src/objects/Mesh";
import { Point } from "../../Engine";
import { FrontSide, BackSide, MeshBasicMaterial, TextureLoader, Texture, ShapePath, ShapeGeometry, Vector3 } from "three";
import Const from "../../application/constants/Const";
import CustomPlaneGeometry from "../../renderExtension/geometriy/CustomPlaneGeometry";
/**
 * 多边形物体
 */
export default class Polygon extends Mesh {
    public renderSide;
    public isBuildPolygonSuccess = true; //构建多边形是否成功
    public data: {pointArray: Array<Point>, textureImg?: string, alphaValue?: number, color?: string, transparent?:boolean, colorWrite?: boolean, depthTest?: boolean, height?:number};

    /**
     * 构建多边形mesh的构造函数
     * @param data 构建多边形需要的参数
     * @param data.pointArray 构建多边形需要的顶点数组，数组中的元素是Point类型的对象
     * @param data.textureImg 贴到多边形上的图片
     * @param data.alphaValue 多边形的透明度
     * @param data.color 多边形的颜色
     * @param data.transparent 是否透明, 可选参数，默认为false
     * @param data.colorWrite 是否写入颜色，可选参数，默认为true
     * @param data.depthTest 是否深度测试，可选参数，默认为false
     * @param data.height 多边形的高度，可选参数，默认为0
     * @example  let img = 'http://localhost:9000/examples/assets/img_logo.39362dc1.png';
        let pointArray = [ //3857表示web墨卡托坐标系，4326表示经纬度坐标
            new GE.Point(13376713.90129997, 3540579.2959903134, 0, '3857'),
            new GE.Point(13376711.98134067, 3539826.5375406537, 0, '3857'),
            new GE.Point(13377952.49603797, 3539759.3270052206, 0, '3857'),
            new GE.Point(13378008.185227688, 3540675.3111583497, 0, '3857'),
            new GE.Point(13377184.375437068, 3540339.2581293588, 0, '3857')
        ];
        let polygonData = {
            pointArray: pointArray,  //多边形的顶点数组
            textureImg: img, //贴在多边形上的图片
            alphaValue: 1,  //透明值
            color: '#FF1493' //多边形的颜色
        };
        let polygon = new GE.Polygon(polygonData);
        app.add(polygon);
     */
    constructor(data: {pointArray: Array<Point>, textureImg?: string, alphaValue?: number, color?: string, transparent?:boolean, colorWrite?: boolean, depthTest?: boolean, height?:number}){
        super();

        this.data = data;
        
        if(data.textureImg){
            this.generateMeshWithTexture(data); //生成带纹理的mesh
        }else{
            this.generateMeshWithoutTexture(data); //生成不带纹理的mesh
        }
    }

    private generateMeshWithTexture(data){ //生成带纹理的mesh
            this.geometry = new CustomPlaneGeometry(data.pointArray, true);
            let earClipData = (this.geometry as CustomPlaneGeometry).earClipData;
    
            this.renderSide = earClipData.isCCW ? FrontSide : BackSide;
            let self = this;
            this.material = new MeshBasicMaterial( {
                map: (data.textureImg != null) ? new TextureLoader().load(data.textureImg, this.onLoadCallback.bind(this), null, this.onErrorCallback.bind(this)) : null,
                color: data.color || '#FFFFFF',
                transparent: (data.transparent == undefined) ? false : data.transparent,
                opacity: data.alphaValue || 1,
                side: self.renderSide,
                depthTest: (data.depthTest == undefined) ? false : data.depthTest,
                colorWrite: (data.colorWrite == undefined) ? true : data.colorWrite,
             } );
    
            let addHeight = data.height || 0;
            this.position.set(earClipData.firstPoint.x, earClipData.firstPoint.y,  earClipData.firstPoint.z + addHeight);
    }

    private generateMeshWithoutTexture(data){ //生成不带纹理的mesh
        let path = new ShapePath();
        let position = data.pointArray[0].clone();
        position.toEPSGWeb();

        data.pointArray.forEach((element, i) => {
            let p = new Point(element.x, element.y, element.z, element.EPSGType || Const.EPSGType.EPSG84);
            p.toEPSGWeb();
            p.sub(position);
            i == 0 ? path.moveTo(p.x, p.y) : path.lineTo(p.x, p.y);
        });

        let geometryShape = path.toShapes(true);
        this.geometry = new ShapeGeometry(geometryShape);
        this.material = new MeshBasicMaterial( {
            color: data.color || '#FFFFFF',
            transparent: (data.transparent == undefined) ? false : data.transparent,
            opacity: data.alphaValue || 1,
            // side: self.renderSide,
            depthTest: (data.depthTest == undefined) ? false : data.depthTest,
            colorWrite: (data.colorWrite == undefined) ? true : data.colorWrite,
         } );

        let addHeight = data.height || 0;
        this.position.set(position.x, position.y,  position.z + addHeight);
    }

    private onLoadCallback(texture: Texture){
        this.material['map'] = texture;
    }

    private onErrorCallback(event){
        this.material['map'] = null;
        this.material['needsUpdate'] = true;
    }

 
    
    
}
